package com.doge.walknovel.payment.google

import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.Purchase
import com.doge.walknovel.analysis.analysisEvent
import com.doge.walknovel.analysis.analysisPurchase
import com.doge.walknovel.api.*
import com.doge.walknovel.api.model.RechargeGoogleSkuInfo
import com.doge.walknovel.core.account.AppUserViewModel
import com.doge.walknovel.utils.*

val Purchase.sku: String? get() = skus.firstOrNull()

object AppPayHelper {
    private const val folder = "googlePay"
    private const val key = "productList"
    private var m: RechargeGoogleSkuInfo? = null

    /** 充值列表. return list[0] inapp list[1] subs */
    fun skuList(callback: (List<String>, List<String>) -> Unit) {
        if (m != null) {
            callback(m?.chargeSkuList ?: listOf(), emptyList())
        } else {
            val disk: String? = spReadString(key, null, folder)
            val cache = fromJson(disk, RechargeGoogleSkuInfo::class.java)
            if (cache != null) {
                m = cache
                callback(m?.chargeSkuList ?: listOf(), emptyList())
            }
        }
        // {"code":200,"data":{"chargeSkuList":["coin_100","coin_500","coin_1000","coin_5000","coin_10000","coin_20000"],"subscriptionSkuList":null}}
        api
            .rechargeGoogleSkuList()
            .map(ApiResultMapTransformer())
            .subscribe(object : ObserverAdapter<RechargeGoogleSkuInfo>() {
                override fun onNext(t: RechargeGoogleSkuInfo) {
                    if (m == null) {
                        callback(t.chargeSkuList ?: listOf(), emptyList())
                    }
                    m = t
                    runOnIO { spWrite(key, toJson(t), folder) }
                }

                override fun onError(e: Throwable) {
                    if (m == null) {
                        callback(listOf(), listOf())
                        feedback("2.sdkDetails loaded", "error request api/rechargeRuleList ${e.message}")
                    }
                }
            })
    }

    // 可能是子线程调用的？
    fun syncPurchase(purchase: Purchase, refer: String?, callback: (nextStep: Boolean) -> Unit) {
        val skuType = skuTypeByProductId(purchase.sku)

        val info = AppBillingClientLifecycle.get().inappSkuDetails.value?.get(purchase.sku)
        analysisPurchase(purchase.sku ?: "", purchase.orderId, "Recharge", info?.priceCurrencyCode, info?.price, info?.priceAmountMicros ?: 0L)

        log("processPurchaseToServer skuType $skuType purchase $purchase info $info")
        val request: io.reactivex.Observable<ApiResult<Any?>> = when (skuType) {
            BillingClient.SkuType.INAPP -> api.rechargeGoogleCallback(
                purchase.signature,
                purchase.originalJson,
                purchase.orderId,
                purchase.sku ?: "",
                "", refer ?: ""
            )
            // BillingClient.SkuType.SUBS -> api.vipSubscriptionCallbackV3(purchase.purchaseToken, purchase.sku)
            else -> null
        } ?: return

        request
            .compose(ApiResultComposeTransformer())
            .subscribeOnIO()
            .observeOnMain()
            .subscribe(object : ObserverAdapter<ApiResult<*>>() {
                override fun onNext(t: ApiResult<*>) {
                    if (!(skuType == BillingClient.SkuType.SUBS && purchase.isAcknowledged)) {
                        feedback("5.service callback", "${purchase.sku} ok") // 已订阅以外场景
                    }
                    next()
                }

                override fun onError(e: Throwable) {
                    if (e is ServerException) {
                        // silently.. 比如已消费. 但是定哥说还是调用一下
                        if (!(skuType == BillingClient.SkuType.SUBS && purchase.isAcknowledged)) {
                            feedback("5.service callback", "${purchase.sku} service error ${e.code} ${e.msg}") // 已订阅以外场景
                        }
                        next()
                    } else {
                        super.onError(e)
                        callback(false)
                        if (!(skuType == BillingClient.SkuType.SUBS && purchase.isAcknowledged)) {
                            feedback("5.service callback", "${purchase.sku} request error ${e.message}") // 已订阅以外场景
                        }
                    }
                }

                private fun next() {
                    callback(true)   // 不用管服务器结果.
                    AppUserViewModel.get().requestSelfInfo() // 刷余额
                }
            })
    }

    // 业务服务器设定逻辑 by 阿定
    fun skuTypeByProductId(productId: String?): String {
        log("skuTypeByProductId productId $productId [${BillingClient.SkuType.SUBS}|${BillingClient.SkuType.INAPP}]")
        return when {
            productId == null -> ""
            productId.contains("subs") -> BillingClient.SkuType.SUBS
            productId.contains("coin") -> BillingClient.SkuType.INAPP
            else -> ""
        }
    }

    private fun feedback(step: String, remark: String) {
        feedback(AppBillingClientLifecycle.TAG, step, remark, retry = 1)
        analysisEvent(step)
    }

}



